package repository

import (
	"context"
	"time"

	"github.com/devops-smartbot/devops-smartbot/services/api-gateway/internal/models"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type SettingsRepository struct {
	systemCol       *mongo.Collection
	notificationCol *mongo.Collection
	integrationCol  *mongo.Collection
	preferenceCol   *mongo.Collection
}

func NewSettingsRepository(db *mongo.Database) *SettingsRepository {
	return &SettingsRepository{
		systemCol:       db.Collection("system_settings"),
		notificationCol: db.Collection("notification_settings"),
		integrationCol:  db.Collection("integrations"),
		preferenceCol:   db.Collection("user_preferences"),
	}
}

// System Settings
func (r *SettingsRepository) GetSystemSettings(ctx context.Context) (*models.SystemSettings, error) {
	var settings models.SystemSettings
	err := r.systemCol.FindOne(ctx, bson.M{}).Decode(&settings)
	if err == mongo.ErrNoDocuments {
		// Return default settings
		return &models.SystemSettings{
			ID:         "default",
			SystemName: "DevOps SmartBot",
			Language:   "en",
			Theme:      "light",
			UpdatedAt:  time.Now(),
			UpdatedBy:  "system",
		}, nil
	}
	return &settings, err
}

func (r *SettingsRepository) UpdateSystemSettings(ctx context.Context, settings *models.SystemSettings) error {
	settings.UpdatedAt = time.Now()
	filter := bson.M{}
	update := bson.M{"$set": settings}
	upsert := true
	opts := &options.UpdateOptions{
		Upsert: &upsert,
	}
	_, err := r.systemCol.UpdateOne(ctx, filter, update, opts)
	return err
}

// Notification Settings
func (r *SettingsRepository) GetNotificationSettings(ctx context.Context, userID string) (*models.NotificationSettings, error) {
	var settings models.NotificationSettings
	err := r.notificationCol.FindOne(ctx, bson.M{"userId": userID}).Decode(&settings)
	if err == mongo.ErrNoDocuments {
		// Return default settings
		return &models.NotificationSettings{
			UserID:              userID,
			EmailNotifications:  true,
			AlertNotifications:  true,
			TicketNotifications: false,
			UpdatedAt:           time.Now(),
		}, nil
	}
	return &settings, err
}

func (r *SettingsRepository) UpdateNotificationSettings(ctx context.Context, settings *models.NotificationSettings) error {
	settings.UpdatedAt = time.Now()
	filter := bson.M{"userId": settings.UserID}
	update := bson.M{"$set": settings}
	upsert := true
	opts := &options.UpdateOptions{
		Upsert: &upsert,
	}
	_, err := r.notificationCol.UpdateOne(ctx, filter, update, opts)
	return err
}

// Integrations
func (r *SettingsRepository) ListIntegrations(ctx context.Context) ([]models.Integration, error) {
	cursor, err := r.integrationCol.Find(ctx, bson.M{})
	if err != nil {
		return nil, err
	}
	defer cursor.Close(ctx)

	var integrations []models.Integration
	if err := cursor.All(ctx, &integrations); err != nil {
		return nil, err
	}
	return integrations, nil
}

func (r *SettingsRepository) GetIntegration(ctx context.Context, id string) (*models.Integration, error) {
	var integration models.Integration
	err := r.integrationCol.FindOne(ctx, bson.M{"_id": id}).Decode(&integration)
	return &integration, err
}

func (r *SettingsRepository) CreateIntegration(ctx context.Context, integration *models.Integration) error {
	integration.CreatedAt = time.Now()
	integration.UpdatedAt = time.Now()
	_, err := r.integrationCol.InsertOne(ctx, integration)
	return err
}

func (r *SettingsRepository) UpdateIntegration(ctx context.Context, id string, integration *models.Integration) error {
	integration.UpdatedAt = time.Now()
	filter := bson.M{"_id": id}
	update := bson.M{"$set": integration}
	_, err := r.integrationCol.UpdateOne(ctx, filter, update)
	return err
}

func (r *SettingsRepository) DeleteIntegration(ctx context.Context, id string) error {
	_, err := r.integrationCol.DeleteOne(ctx, bson.M{"_id": id})
	return err
}

// User Preferences
func (r *SettingsRepository) GetUserPreference(ctx context.Context, userID string) (*models.UserPreference, error) {
	var pref models.UserPreference
	err := r.preferenceCol.FindOne(ctx, bson.M{"userId": userID}).Decode(&pref)
	if err == mongo.ErrNoDocuments {
		// Return default preferences
		return &models.UserPreference{
			UserID:       userID,
			ItemsPerPage: 10,
			Timezone:     "UTC",
			DateFormat:   "YYYY-MM-DD",
			DefaultView:  "dashboard",
			UpdatedAt:    time.Now(),
		}, nil
	}
	return &pref, err
}

func (r *SettingsRepository) UpdateUserPreference(ctx context.Context, pref *models.UserPreference) error {
	pref.UpdatedAt = time.Now()
	filter := bson.M{"userId": pref.UserID}
	update := bson.M{"$set": pref}
	upsert := true
	opts := &options.UpdateOptions{
		Upsert: &upsert,
	}
	_, err := r.preferenceCol.UpdateOne(ctx, filter, update, opts)
	return err
}
